home *** CD-ROM | disk | FTP | other *** search
- ! C68 Floating Point error routines
- !
- ! If return made from the raise() system call, then an
- ! appropriate value is passed back in d0 and d1.
- !
- ! The values involved are such that 'float' routines
- ! can simply take the d0 value
- !
- !-----------------------------------------------------------------------------
- ! #1 First version (based on ideas from Michael Mueller) djw- 09/93
- !-----------------------------------------------------------------------------
-
- .sect .text
-
- .define __huge_val
- .define __infinity
- .define __infinitydf
- .define __NaN
- .define __SNaN
-
- .define .overflow
- .define .underflow
- .define .divzero
- .define .setmaxmin
-
- ! This next bit handles the sizeof(int) problem
-
- #include <errno.h>
- #include <signal.h>
-
- #ifdef __MSHORT__
- #define LN w
- LEN = 2
- #else
- #define LN l
- LEN = 4
- #endif
-
-
- ! This is the representation of key floating point values.
- !
- ! It is done this way, because it is quite likely that rounding errors
- ! in the compiler might mean the bit pattern is not exactly represented
- ! if simply done via a #define statement.
-
-
- ! Maximum Floating Point Number (can be signed)
- __huge_val:
- .data4 0x7fefffff,0xffffffff
-
- ! Infinity (can be signed)
- __infinity:
- __infinitydf:
- .data4 0x7ff00000,0x00000000
-
- ! Not-a-Number
- __NaN:
- .data4 0x7fffffff,0xffffffff
-
- ! Signalling Not-a-Number
- __SNaN:
- .data4 0xffffffff,0xffffffff
-
-
- ! Overflow has occurred
- ! We need to raise a floating point exception, with errno
- ! set to ERANGE. If a return is made from the exception
- ! routine, then return HUGE_VAL
-
- .overflow:
- move.LN #ERANGE,_errno ! errno = ERANGE for overflow
- bsr sendsig
- move.l __huge_val(pc),d0 ! result = HUGE_VAL in case of return
- move.l __huge_val+4(pc),d1
- rts
-
- ! Underflow has occurred
- ! We need to raise a floating point exception, with errno
- ! set to ERANGE. If a return is made from the floating
- ! routine, then return 0.
- !
- .underflow:
- move.LN #ERANGE,_errno ! errno = ERANGE for underflow
- bsr sendsig
- move.l #0,d0 ! result = 0 in case of return
- move.l #0,d1
- rts
-
- ! Divide by Zero
- ! We need to raise a flaoting point exception with errno set to EDOM.
- ! If a return is made from the exception routine, then return infinity.
-
- .divzero:
- move.LN #EDOM,_errno ! errno = EDOM for divide by zero
- bsr sendsig
- move.l __infinity(pc),d0 ! result = infinity in case of return
- move.l __infinity+4(pc),d1
- rts
-
- ! Send a signal.
- ! We also preserve A1 across this call as many of the FP support routines
- ! use this to hold a pointer to where the result is meant to be put.
- ! Most of the time we will not return from such a call, but ithe calling
- ! routines better be prepared to handle this just in case.
-
- sendsig:
- move.l a1,-(sp) ! save a1
- move.LN #SIGFPE,-(sp) ! set for signal required
- jsr _raise ! raise (SIGFPE) (with name hiding)
- add.l #LEN,sp ! tidy up stack
- move.l (sp)+,a1 ! restore a1
- rts
-
- ! Set LONG_MAX or LONG_MIN
- ! This is used to set LONG_MAX or LONG_MIN according to the sign of the
- ! floating point number pointed to by 8(A0)
- ! (called by sftol() and dftol() routines)
-
- .setmaxmin:
- move.l 8(sp),a0 ! address of value
- move.b (a0),d1 ! get value
- and.b 0x80,d1 ! isolate sign
- bne setmin ! ... jump if negative
- move.l #0x7fffffff,d0 ! set to LONG_MAX
- rts
- setmin: move.l #0x80000000,d0 ! set to LONG_MIN
- rts
-